package com.uxsino.reactorq.model;

import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.uxsino.reactorq.commons.IFlowItem;

/**
 * 
 * generally it represents query result of an indicator
 * but due to legacy of design, it is mixed with some control/status message
 * of querying. 
 * when the entityId starts with '#', it is an internal message instead of value
 * FLOW_CONTROL means flow control message.
 *
 */
public class IndicatorValue implements IFlowItem {
    public enum TYPE {
                      TaskStatus,
                      Value,
                      RequestSeq,
                      FailedMsg,
                      ErrorMsg,
                      DisconnMsg;
    }

    @JsonProperty("seq")
    @JSONField(name = "seq")
    public String sequenceId;

    @JsonProperty("tid")
    @JSONField(name = "tid")
    public String taskId;

    @JsonProperty("tm")
    @JSONField(name = "tm")
    public long queryTimeMillis;

    @JsonProperty("cost")
    @JSONField(name = "cost")
    public long cost;

    @JsonProperty("ne")
    @JSONField(name = "ne")
    public String entityId;

    @JsonProperty("ind")
    @JSONField(name = "ind")
    public String indicatorName;

    @JsonProperty("v")
    @JSONField(name = "v")
    public Object value;

    @JsonProperty("type")
    @JSONField(name = "type")
    public TYPE type;

    public IndicatorValue() {
        this.type = TYPE.Value;
    }

    public IndicatorValue(String entityId, String indicatorName, Object value) {
        this.entityId = entityId;
        this.indicatorName = indicatorName;
        this.value = value;
        this.type = TYPE.Value;
    }

    @Override
    public String toString() {
        return entityId + "." + indicatorName + ":" + (value == null ? "null" : value.toString());
    }

    /**
     *  this is an internal message about task, not an indicator queried
     * @return
     */
    @JsonIgnore
    @JSONField(serialize = false)
    public boolean isInternal() {
        return entityId.charAt(0) == '#';
    }

    public STATUS getStatus() {
        return FLOW_CONTROL.equals(entityId) ? STATUS.valueOf(value.toString()) : STATUS.RUNNING;
    }
}
